/*----------------------------------------------------------
* FILE: GeneralFunction.java
* LOGICAL NAME: GeneralFunction
* PRODUCT: bila-framework
*----------------------------------------------------------
* MODIFICATIONS
* DATE Oct 7, 2011
* AUTHOR wjuarez
*----------------------------------------------------------
*/

package bila.framework.commons;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author WJuarez
 * <b>Created by </b>wjuarez
 * <b>for</b> bila-framework
 * <b>package</b> bila.framework.commons
 * <b>on</b> Oct 7, 2011 8:21:54 PM
 * <b>Purpose</b> 
 * <p>
 *		Funciones comunes
 * </p>
 */
public class GeneralFunction {

	/**
	 * Verifica si el objeto esta vacio o nulo
	 * @param obj objeto que se desea verificar
	 * @return true en caso de ser cierto y en caso contrario false
	 */
	public static boolean isNullOrEmpty(Object obj) {
		if (obj == null || obj.toString().length() < 1 || obj.toString().equals(Constants.EMPTY_STRING))
			return true;
		return false;
	}

	/**
	 * Verifica si el objeto esta nulo, vacio o si contiene cero
	 * @param obj objeto que se desea verificar
	 * @return true en caso de ser cierto y en caso contrario false
	 */
	public static boolean isNullOrEmptyOrZero(Object obj) {
		if (obj == null
				|| obj.toString().length() < 1
				|| obj.toString().equals(Constants.EMPTY_STRING)
				|| ((obj instanceof Long && obj.equals(0L)) || (obj instanceof Integer && obj.equals(0)) || (obj instanceof Float && obj.equals(0.00)) || (obj instanceof Double && obj
						.equals(0.00)))) {
			return true;
		}
		return false;
	}

	/**
	 * Verifica si el objeto es nulo, si es asi devuelve el valor del
	 * segundo parametro (val) en caso contrario devuelve el valor del
	 * objeto como tal
	 * @param obj objeto que se desea verificar si es nulo
	 * @param val objeto que devolvera en caso el primero es nulo
	 * @return valor del objeto dependiendo si es nulo o no
	 */
	public static Object nvl(Object obj, Object val) {
		if (isNullOrEmpty(obj)) {
			return val;
		}
		return obj;
	}

	/**
	 * Verifica si el String es nulo, de ser asi devuelve la cadena N/A
	 * en caso contrario devuelve el string que se pasa como parametro
	 * @param str String que se desea verificar
	 * @return devuelve un String
	 */
	public static String emptyWhenNull(String str) {
		return (String) nvl(str, "N/A");
	}
	
	/**
	 * Retorna 0 si el double es nulo, en caso contrario devuelve su 
	 * propio valor
	 * @param d Double que se desea verificar
	 * @return Double o cero
	 */
	public static Double zeroWhenNull(Double d){
		return (Double) nvl(d, 0);
	}
	
	/**
	 * Retorna 0 si el intero es nulo, en caso contrario devuelte su
	 * propio valor
	 * @param i Integer que se desea verificar
	 * @return Integer o cero
	 */
	public static Integer zeroWhenNull(Integer i){
		return (Integer) nvl(i, 0);
	}
	
	/**
	 * Redondea el double que se pasa como primer parametro con el numero
	 * de decimales que se pasa como segundo parametro
	 * @param d double que se desea redondear
	 * @param decimalPlace numero de decimales que se desean
	 * @return double redondeado
	 */
	public static double round(double d, int decimalPlace) {
		BigDecimal bd = new BigDecimal(Double.toString(d));
		bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

	/**
	 * Redondea el valor de tipo double a 2 decimales
	 * @param d numero que se desea redondear
	 * @return objeto double con dos decimales
	 */
	public static double round(double d) {
		BigDecimal bd = new BigDecimal(Double.toString(d));
		bd = bd.setScale(Constants.DECIMAL_PLACES, BigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

	/**
	 * Redondea el objeto BigDecimal a 2 decimales
	 * @param d numero que se desea redondear
	 * @return objeto de tipo BigDecimal con 2 decimales
	 */
	public static double round(BigDecimal d) {
		d = d.setScale(Constants.DECIMAL_PLACES, BigDecimal.ROUND_HALF_UP);
		return d.doubleValue();
	}
	
	/**
	 * Recupera la fecha actual
	 * @return fecha actual en objeto de tipo Date
	 */
	public Date getDate(){
		return Calendar.getInstance().getTime();
	}
	/**
	 * Convierte la primera letra de la palabra en mayuscula
	 * @param text texto que se desea convertir
	 * @return texto con la primera letra en mayuscula
	 */
	public static String firstUpper(String text) {
		return Character.toUpperCase(text.charAt(0))+text.substring(1).toLowerCase();		
	}
	
	/**
	 * Convierte la primera letra del texto
	 * en miniscula
	 * @param text objeto String que desea modificarse
	 * @return objeto de tipo String
	 */
	public static String firstLower(String text){
		return Character.toLowerCase(text.charAt(0))+text.substring(1);
	}
	
	/**
	 * Convierte la ultima letra de la palabra en mayuscula
	 * @param text texto que se desea convertir
	 * @return texto con la ultima letra en mayuscula
	 */
	public static String lastUpper(String text) {
		int n = text.length();
		return text.substring(0,n-1)+Character.toUpperCase(text.charAt(n-1));
	}
	
	/**
	 * Convierte la primera letra de cada palabra en mayuscula y las demas en miniscula
	 * @param input texto que se desea convertir
	 * @return Texto con funcion initcap
	 */
	public static String initcap(String input) {			
			Pattern p = Pattern.compile ("("+
				"(\\w?')|"+
				"(\\w|')+"+
			")");
			Matcher m = p.matcher (input);
			StringBuffer sb = new StringBuffer ();
			while (m.find ()) {
				m.appendReplacement (sb, firstUpper(m.group()));
			}
			m.appendTail (sb);
			
			p = Pattern.compile ("([Mm][Aa]?[Cc](\\w))");
			m = p.matcher (sb.toString());
			sb = new StringBuffer ();
			while (m.find ()) {
				m.appendReplacement (sb, lastUpper(m.group()));
			}
			m.appendTail (sb);
			return sb.toString();
	}
	
	/**
	 * Modifica un string que posee codigos que no se acepta en HTML
	 * @param column texto que desea modificarse
	 * @return String texto con nomenclatura HTML
	 * @throws Exception
	 */
	public static String generateHtml(String column) throws Exception{
		if(column.contains("á"))
			column = column.replace("á", "&aacute;");
		if(column.contains("Á"))
			column = column.replace("Á", "&Aacute;");
		if(column.contains("é"))
			column = column.replace("é", "&eacute;");
		if(column.contains("É"))
			column = column.replace("É", "&Eacute;");
		if(column.contains("í"))
			column = column.replace("í", "&iacute;");
		if(column.contains("Í"))
			column = column.replace("Í", "&Iacute;");
		if(column.contains("ó"))
			column = column.replace("ó", "&oacute;");
		if(column.contains("Ó"))
			column = column.replace("Ó", "&Oacute;");
		if(column.contains("ú"))
			column = column.replace("ú", "&uacute;");
		if(column.contains("Ú"))
			column = column.replace("Ú", "&Uacute;");
		if(column.contains("ñ"))
			column = column.replace("ñ", "&ntilde;");
		if(column.contains("Ñ"))
			column = column.replace("Ñ", "&Ntilde;");
		return column;
	}
	
	/**
	 * Devuelve el año actual
	 * @return entero con el año actual
	 * @throws Exception
	 */
	public static int getYear() throws Exception{
		Calendar cal = Calendar.getInstance();
    	Integer year = cal.get(Calendar.YEAR);
    	return year;
	}
	
	/**
	 * Devuelve el mes actual
	 * @return entero con el mes actual
	 * @throws Exception
	 */
	public static int getMonth() throws Exception{
		Calendar cal = Calendar.getInstance();
		Integer month = cal.get(Calendar.MONTH);
		return month;
	}
	
}
